package com.zkh.myutils.database.helper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import com.zkh.myutils.database.enums.Symbol;
import com.zkh.myutils.utils.ArrayUtils;
import com.zkh.myutils.utils.Assert;
import com.zkh.myutils.utils.Utils;

/**
 * 条件块解析结果对象
 * @author zkh
 */
class ConditionPartResult {
	//组装好的SQL条件
	private StringBuilder condition = new StringBuilder();
	//对应的参数
	private List<Object> paramList = new ArrayList<>();

	/**
	 * 获取条件块组装结果
	 */
	public static ConditionPartResult getConditionPartString(List<ConditionPart> conditionPartList) {
		//创建结果容器
		ConditionPartResult result = new ConditionPartResult();
		//开始遍历条件块
		for(ConditionPart part: conditionPartList) {
			//逻辑
			Symbol l = part.getLogic();
			//逻辑块不为空
			if(l==Symbol.AND || l==Symbol.OR) {
				result.appendCondition(l.symbol);
			}
			//Relation
			Relation r = part.getRelation();
			//解析Relation
			if(r!=null) {
				//临时变量
				String k = r.getField(); Symbol c = r.getSign(); Object v = r.getValue();
				boolean p = r.isPlaceholder();
				//键为空
				if(k==null && (c==Symbol.EXISTS || c==Symbol.NOTEXISTS)) {
					result.appendCondition(c.symbol + "(" + v + ")");
				}else if(k!=null) {
					//值为null或比较符为NULL或NOTNULL
					if(v==null || c==Symbol.NULL || c==Symbol.NOTNULL) {
						result.appendCondition(k + (c==Symbol.NOTNULL ? " is not null " : " is null "));
					}
					//BETWEEN连接符
					else if(c==Symbol.BETWEEN || c==Symbol.NOTBETWEEN) {
						//获取值（值必须是长度为2的数组）
						Object[] vs = ArrayUtils.getArray(v);
						//追加SQL
						result.appendCondition(k + c.symbol + Assert.getIfElse(p, "?", vs[0]) + " and " + Assert.getIfElse(p, "?", vs[1]));
						//占位，保存参数
						if(p) {result.addParam(vs[0]);result.addParam(vs[1]);}
					}
					//IN或NOTIN连接符
					else if(c==Symbol.IN || c==Symbol.NOTIN) {
						//处理值
						Object[] vs = v instanceof Collection ? ((Collection<?>) v).toArray() : (v.getClass().isArray() ? ArrayUtils.getArray(v) : new Object[] {v});
						//取值
						Object[] tvs = p ? ArrayUtils.getArray(String.class, vs.length, "?") : vs;
						//追加SQL
						result.appendCondition(k + c.symbol + "(" + Utils.join(",", tvs) + ")");
						//占位
						if(p) result.getParamList().addAll(Arrays.asList(vs));
					}
					//LIKE连接符
					else if(c==Symbol.LIKE || c==Symbol.NOTLIKE) {
						//追加SQL
						result.appendCondition(k + c.symbol + Assert.getIfElse(p, "?", "'%" + v + "%'"));
						//占位
						if(p) result.addParam("%" + v + "%");
					}
					//其它连接符
					else {
						//追加SQL
						result.appendCondition(k + c.symbol + Assert.getIfElse(p, "?", v));
						//占位
						if(p) result.addParam(v);
					}
				}
			}else {
				//子条件块
				List<ConditionPart> children = part.getChildrenPart();
				//递归计算结果
				ConditionPartResult childrenResult = getConditionPartString(children);
				//子条件块中有多个条件块，要添加括号
				if(children.size()>1) {
					result.appendCondition("(" + childrenResult.getCondition() + ")");
				}else {
					result.appendCondition(childrenResult.getCondition());
				}
				//拼接参数
				result.getParamList().addAll(childrenResult.getParamList());
			}
		}
		return result;
	}
	
	/**
	 * 条件是否为空
	 */
	public boolean isEmpty() {
		return condition.toString().isEmpty();
	}
	
	/**
	 * 获取组装条件SQL
	 */
	public String getCondition() {
		return condition.toString();
	}
	
	/**
	 * 获取参数列表
	 */
	public List<Object> getParamList() {
		return paramList;
	}
	
	/**
	 * 追加条件
	 */
	private void appendCondition(String condition) {
		this.condition.append(condition);
	}
	/**
	 * 添加参数
	 */
	private void addParam(Object value) {
		this.paramList.add(value);
	}
}
